Appendix A - Embedding Checklist
This appendix summarizes the capabilities that your part editor must have if it is to support embedding. If you want your parts to be container parts, you must implement these features in your code.Keep in mind that handling embedded parts usually means handling embedded frames; in most cases, your part directly interacts only with the frames of the parts embedded in it. Those embedded frames in turn interact with the parts displayed in them, and the embedded parts interact with their own embedded frames, and so on, down through the embedding hierarchy.
This checklist is meant for quick reference only. The items in the list are discussed in greater detail elsewhere in this book.
Content Model and Storage
- Add embedding to your part's content model. Create a content element that you can track and manipulate to represent an embedded frame. You might create a proxy object that can represent a frame in both its stored and in-memory state.
- Maintain a list of the frames embedded in your part. Implement an iterator (a subclass of
ODEmbeddedFramesIterator
) to allow callers access to the frame objects in the list. Implement your part'sCreateEmbeddedFramesIterator
method, through which callers instantiate the class.- When you write your part to storage, write persistent references to your embedded frames into your part's content stream. (Do not write them into a separate property.) When you read your part from storage, reconstruct your embedded frames from the stored persistent references in your content.
For efficiency, you can use lazy creation for this purpose. Create a frame object for each embedded frame only when you need to display it. Purge unneeded frames when requested.
Embedded-Frame Management
Depending on your part's content model and features, you may also want to add support for these capabilities:
- You control the sizes and locations of your embedded frames. Support frame negotiation, if appropriate, in your
RequestFrameShape
method.- Be prepared to receive requests for additional frames from an embedded part. Implement your
RequestEmbeddedFrame
method, and handle calls to it as appropriate for your content model.If you add a requested frame, use the requested shape for both sizing and relative positioning of the frame, if your content model allows it. Normalize the frame shape that you return. Give the frame an appropriate group ID and sequence number.
If you grant requests for additional embedded frames, implement your part's
RemoveEmbeddedFrame
method so that embedded parts can have you delete those frames when they are no longer needed.- If you create an embedded frame that displays the same content in the same presentation as another embedded frame, use
AttachSourceFrame
to have the embedded part attach the new frame to the original (source) frame, so that updates in one will be reflected in the other.- When you no longer need an embedded frame, permanently remove it by removing all of its facets, setting its containing frame to null, and calling its
Release
orRemove
method, as appropriate.- Another part may request that you scroll your part's content to reveal an embedded frame. You may have to accomplish this by scrolling your own content, or by requesting that your containing part scroll its content. Implement your part's
RevealFrame
method to fulfill this request.- Support undo of all embedded-frame manipulations.
- If you support sequenced frames, use frame groups to define sets of sequentially ordered embedded frames. Assign sequence numbers so that the embedded part can know in what order to fill its frames with content.
- If your content model suggests that you should make any of your content properties (such as, for example, text font or style) available for adoption by embedded parts, implement your
AcquireContainingPartProperties
method so that embedded parts can call it. Likewise, call your embedded parts'ContainingPartPropertiesUpdated
method whenever you change any of your adoptable content properties.- Whether or not you support linking, implement your part's
LinkStatusChanged
method, so that you can call your embedded
frames'ChangeLinkStatus
methods and communicate changes in
your own display frame's link status.
Drawing
Depending on your part's content model and features, you may also want to add support for these capabilities:
- Define the initial view type (icon or frame) that embedded parts should have. By convention, most embedded parts should have frame view type.
- Create facets for all of your visible embedded frames. Add facets as frames become visible; remove facets or mark them as purgeable when frames are no longer visible.
- When a frame embedded in your part is the active frame, you need to clip whatever content the active frame border obscures, and you also need to clip the active frame border where your content obscures it. Implement your part's
AdjustBorderShape
method for this purpose.- Support selection of your embedded frames. Highlight a selected embedded frame by drawing the selected frame border (and resize handles, if you support resizing of embedded frames) on the embedded frame's frame shape, not its used shape.
- When a range selection includes an embedded frame, give the embedded part's facet the highlight style the embedded part should adopt to be consistent with your highlighting model.
- When your part is displayed in thumbnail view type, you are responsible for integrating miniature representations of any visible embedded parts into the thumbnail.
- If you support overlapping of embedded frames and intrinsic content, maintain the proper clip shapes for all of your embedded frames' facets. Maintain a z-ordered list of your embedded facets, and use it to account for overlaps with other embedded frames and with your part's content elements.
- If you wrap your content to the used shape of your embedded parts, implement your part's
UsedShapeChanged
method, so that embedded parts can notify you when that used shape changes.- If you create offscreen canvases, implement your part's
CanvasUpdated
method so that you can transfer your embedded parts' asynchronous drawing to your parent canvas.- If you support split-frame views of embedded parts, provide multiple facets for your embedded frames.
Event Handling
Depending on your part's content model and features, you may also want to add support for these capabilities:
- Handle these events that occur within and on the borders of an embedded frame's facet:
kODEvtMouseDownEmbedded
,kODEvtMouseUpEmbedded
,kODEvtMouseDownBorder
,kODEvtMouseUpBorder
, andkODEvtBGMouseDownEmbedded
. Use these events to initiate a drag of the embedded frame, to select the embedded frame, or to activate your own part.- Enable and respond to these items in the Document menu:
- Open Selection: open a selected embedded frame into a window. (Also support double-clicking on a selected icon to open it.)
- Insert: embed a user-chosen part into your part. Handle as described under "Data Transfer" in this checklist.
- Enable and respond to these items in the Edit menu:
- Undo, Redo: include embedded frames in the actions that you save and restore.
- Cut, Copy, Paste, Paste As: include embedded frames in the data you manipulate. Handle as described under "Data Transfer" in this checklist.
- Selection Info: Display a selected embedded frame's Part Info dialog box.
- If you want to receive events sent to an embedded frame that its part chooses not to handle, set the event-propagating flag of the frame when you create it.
- If you support resizing of embedded frames, use mouse-down events in resize handles of selected embedded frames to initiate resize operations.
Data Transfer
General
Cutting Data
- Modify your basic routines for writing and reading data to account for embedded parts. This includes transfers involving the clipboard, the drag-and-drop object, link-source objects, link objects, other parts (as per the Insert command), and fulfilled promises.
- Do all reading and writing in the context of cloning. In addition to reading and writing intrinsic data, clone embedded frames (and other referenced objects) to or from the storage units involved.
- If you write a single embedded part, you should also write its frame as an annotation to the storage unit. If you read a single embedded part, use that annotated frame as the frame of the part you read.
- Modify your part's
CloneInto
method to add cloning of your part's embedded parts.
- Follow the conventions for receiving transferred data. Incorporate the data if your part editor can read it; otherwise, embed it as a separate part.
- Modify your handling of the Paste As dialog box: allow the user to select the Embed As button.
Linking
- If you cut (or drag-move) data from your part that includes embedded frames, keep these cautions in mind:
- Don't assume that removing one embedded frame removes a part entirely; other frames of the part may still be embedded in your part.
- Be sure to set the containing frame of each removed frame to null, since it is no longer embedded in your part.
- Use your own display facet's embedded facet iterator to delete the facets of each frame that was removed.
- Be sure to remove or release, rather than delete, each cut frame object. To support undo, do that only when your part's
DisposeActionState
method is called.
- Implement your part's
EditInLinkAttempted
method, so that embedded parts can notify you when the user attempts to edit their data when it is part of a link destination that you maintain.- Call the
ChangeLinkStatus
method of any embedded frame that becomes part of, or ceases to be part of, a link source or destination that you maintain.- Implement your part's
EmbeddedFrameUpdated
method, so that embedded frames can notify your part when their content has changed and your part can in turn update any link sources involving that embedded content.
For Scripting Support
- In your content model, create a content object that represents an embedded frame. Create an object accessor for embedded frames, if you want access to any custom information about your embedded frames. (OpenDoc provides a default accessor that can access an embedded frame or any of its standard user properties.)
- Write a semantic-event handler that can manipulate any of an embedded frame's properties that you define, such as its position or its selection state. (Semantic events involving standard user properties of the embedded frame's part will be passed to the part itself.)
- Implement your part's
EmbeddedFrameSpec
method, to create an object accessor for your embedded frame.
Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help